import logging
import telnetlib
import time
import re

class TelnetObj():
    _ip = ''
    _usernm = ''
    _passwd = ''
    _tn = None
    _expire_time = 0

    def __init__(self,ip,passwd):
        self._ip = ip;
        self._passwd = passwd;
        self._tn = telnetlib.Telnet()
        self._tn.open(self._ip, 23) 
        self._expire_time = time.time() + 600
        if not self.login():
            print('登录失败')
            # return '登录失败'
    # 更新过期时间
    def update_expire_time(self):
        # 如果已经过期
        if time.time() > self._expire_time:
            # 重新建立一个链接
            self._tn.open(self._ip, 23) 
            if not self.login():
                print('登录失败')

        # 更新过期时间 
        self._expire_time = time.time() + 600;

    # 退出telnet
    def logout_host(self):
        self._tn.write(b"exit\n")
    # 此函数实现telnet登录主机
    def login(self):
        # 等待login出现后输入用户名，最多等待10秒
        self._tn.read_until(b'login: ',timeout = 5)
        # 等待Password出现后输入用户名，最多等待10秒
        self._tn.read_until(b'Password: ',timeout = 5)
        # 输入密码
        self._tn.write(self._passwd.encode('ascii') + b'\n')
        # 延时一秒再收取返回结果，给服务端足够响应时间
        time.sleep(1)
        # 获取登录结果
        # read_very_eager()获取到的是的是上次获取之后本次获取之前的所有输出
        command_result = self._tn.read_very_eager().decode('ascii')
        # print(command_result)
        if 'Login incorrect' not in command_result:
            # logging.warning('%s登录成功'%host_ip)
            print('登录成功')
        self._tn.write('en'.encode('ascii') + b'\n')
            # self._execute_one_command(tn,['en'])
            # 等待Password出现后输入用户名，最多等待10秒
        self._tn.read_until(b'Password: ',timeout = 5)
            # 输入密码
        self._tn.write(self._passwd.encode('ascii') + b'\n')

        command_result = self._tn.read_very_eager().decode('ascii')
        if '#' not in command_result:
            # logging.warning('%s登录成功'%host_ip)
            print('特权获取成功')
        return True;

    # 此函数实现执行传过来的命令，并输出其执行结果
    def _execute_one_command(self,tn,command):
        # 执行命令
        self._tn.write(command.encode('ascii') + b'\n')
        self._tn.write(b'\n')
        time.sleep(1)
        # 获取命令结果
        return tn.read_very_eager().decode('ascii')


    # 执行一条命令并缓慢的获得输出
    def execute_query_command_slowly(self, command):
        # 执行命令
        self._tn.write(command.encode('ascii') + b'\n')
        self._tn.write(b'\n')
        # 等待一个较长的时间，确保命令都执行完毕了
        time.sleep(10)
        # 获取命令结果
        return self._tn.read_very_eager().decode('ascii')
    # 执行多条命令
    def _execute_many_commands(self,tn,commands):

        res = ''
        for command in commands:
            print('执行%s' % command)
            # 执行命令
            self._tn.write(command.encode('ascii') + b'\n')
            self._tn.write(b'\n')
            time.sleep(1)
            res += self._tn.read_very_eager().decode('ascii')
        return res
            # self._execute_one_command(tn,command)

    # 执行配置命令
    def execute_conf_commands(self,commands):
        self.update_expire_time()

        self._tn.write('conf term'.encode('ascii') + b'\n')
        command_result = self._tn.read_very_eager().decode('ascii')
        
        print(command_result)  
        # 执行用户输入的多条命令
        self._execute_many_commands(self._tn,commands)

        self._tn.write('exit'.encode('ascii') + b'\n')
        command_result = self._tn.read_very_eager().decode('ascii')
        
        print(command_result)  
        # except e:
        #     return '网络连接失败'
        

    # 执行查询命令
    def execute_query_command(self ,command):
        self.update_expire_time()
        # 最终返回结果
        return self._execute_one_command(self._tn,command)

if __name__ == '__main__':
    host_ip = '172.16.0.2'
    username = 'CISCO'
    password = 'CISCO'
    command = 'show int '
    telnetObj = TelnetObj(host_ip,password)
    telnetObj.execute_conf_commands(['ip access-list standard test1','10 deny all','exit'])
    # print(telnetObj.execute_query_command(command));
    # time.sleep(3)
    # print(telnetObj.execute_query_command('show ip access-list'));
    # print(telnetObj.execute_query_command('show int f0/1'));

